package org.testile.datasetgenerifier.impl;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.testile.datasetgenerifier.TransformationFactory;

/**
 *
 * @author ytoh
 */
public class ReplaceTransformationFactory implements TransformationFactory {

	public Function<String, String> newInstance(Object o, Map m) {
		List<Function<String,String>> transformations = new ArrayList<Function<String, String>>();

		for (Map.Entry<String,String> entry : ((Map<String,String>)m).entrySet()) {
			transformations.add(new PatternTransformation(Pattern.compile(entry.getKey()), entry.getValue()));
		}

		return composeTransformations(transformations);
	}

	private Function<String, String> composeTransformations(List<Function<String, String>> transformations) {
		int size = transformations.size();
		if(size == 1) {
			return transformations.get(0);
		}

		Function<String,String> composedFunction = Iterators.getLast(transformations.iterator());
		for (Function<String, String> function : Iterables.reverse(transformations.subList(0, size - 1))) {
			composedFunction = Functions.compose(composedFunction, function);
		}
		return composedFunction;
	}

	/**
	 *
	 */
	public static final class PatternTransformation implements Function<String,String> {
		private final Pattern pattern;
		private final String replacement;

		public PatternTransformation(Pattern pattern, String replacement) {
			this.pattern = pattern;
			this.replacement = replacement;
		}

		public String apply(String from) {
			Matcher matcher = pattern.matcher(from);
			return matcher.replaceAll(replacement);
		}
	}
}
